package repo

import (
	"os"
	"strings"
	"unicode"
)

// Cut 用于将指定的输入字符串的第一个部分切下来
func Cut(line string) (string, string) {
	pos := strings.IndexFunc(line, unicode.IsSpace)
	if pos < 0 {
		return line, ""
	}

	if (pos + 1) >= len(line) {
		return line[:pos], ""
	}

	return line[:pos], strings.TrimSpace(line[pos+1:])
}

func CutFunc(line string, sep func(r rune) bool) (string, string) {
	pos := strings.IndexFunc(line, sep)
	if pos < 0 {
		return "", ""
	}

	if (pos + 1) >= len(line) {
		return line[:pos], ""
	}

	return line[:pos], strings.TrimSpace(line[pos+1:])
}

func SplitSet(text string) map[string]bool {
	itemsMapping := make(map[string]bool)
	usagesItems := strings.Split(text, ":")
	for _, usage := range usagesItems {
		usage = strings.TrimSpace(usage)
		if len(usage) == 0 {
			continue
		}
		itemsMapping[usage] = true
	}

	return itemsMapping
}

func JoinSet(set map[string]bool) string {
	items := make([]string, 0, len(set))
	for key := range set {
		items = append(items, key)
	}

	return strings.Join(items, ":")
}

func PathIsExists(path string) bool {
	_, err := os.Stat(path)
	return err == nil
}

func PathIsFile(path string) bool {
	stat, err := os.Stat(path)
	if err != nil {
		return false
	}

	return stat.Mode().IsRegular()
}

func PathIsDir(path string) bool {
	stat, err := os.Stat(path)
	if err != nil {
		return false
	}

	return stat.Mode().IsDir()
}

/*
int wildcmp(const char *wild, const char *string) {
  //// Written by Jack Handy - <A href="mailto:jakkhandy@hotmail.com">jakkhandy@hotmail.com</A>
  //const char *cp = NULL, *mp = NULL;
  //
  //while ((*string) && (*wild != '*')) {
  //  if ((*wild != *string) && (*wild != '?')) {
  //    return 0;
  //  }
  //  wild++;
  //  string++;
  //}
  //
  //while (*string) {
  //  if (*wild == '*') {
  //    if (!*++wild) {
  //      return 1;
  //    }
  //    mp = wild;
  //    cp = string+1;
  //  } else if ((*wild == *string) || (*wild == '?')) {
  //    wild++;
  //    string++;
  //  } else {
  //    wild = mp;
  //    string = cp++;
  //  }
  //}
  //
  //while (*wild == '*') {
  //  wild++;
  //}
  //return !*wild;
}
*/
/*
func wildcmp(pattern string, text string) int {
	//// Written by Jack Handy - <A href="mailto:jakkhandy@hotmail.com">jakkhandy@hotmail.com</A>
	//const char *cp = NULL, *mp = NULL;
	cp := 0
	mp := 0
	str := 0
	wild := 0
	//while ((*string) && (*wild != '*')) {
	for str < len(text) && pattern[wild] != '*' {
		//  if ((*wild != *string) && (*wild != '?')) {
		if pattern[wild] != text[str] && pattern[wild] != '?' {
			//    return 0;
			return 0
			//  }
		}
		//  wild++;
		//  string++;
		wild++
		str++
		//}
	}

	//while (*string) {
	for str < len(text) {
		//  if (*wild == '*') {
		//    if (!*++wild) {
		//      return 1;
		//    }
		//    mp = wild;
		//    cp = string+1;
		//  } else if ((*wild == *string) || (*wild == '?')) {
		//    wild++;
		//    string++;
		//  } else {
		//    wild = mp;
		//    string = cp++;
		//  }
		//}
	}

	//
	//while (*wild == '*') {
	//  wild++;
	//}
	//return !*wild;

}
*/

// Wildcmp -  finds whether the text matches/satisfies the pattern string.
// supports  '*' and '?' wildcards in the pattern string.
// unlike path.Match(), considers a path as a flat name space while matching the pattern.
// The difference is illustrated in the example here https://play.golang.org/p/Ega9qgD4Qz .
func Wildcmp(pattern string, name string) bool {
	if pattern == "" {
		return name == pattern
	}
	if pattern == "*" {
		return true
	}
	rname := make([]rune, 0, len(name))
	rpattern := make([]rune, 0, len(pattern))
	for _, r := range name {
		rname = append(rname, r)
	}
	for _, r := range pattern {
		rpattern = append(rpattern, r)
	}
	simple := false // Does extended wildcard '*' and '?' match.
	return deepMatchRune(rname, rpattern, simple)
}

func deepMatchRune(str, pattern []rune, simple bool) bool {
	for len(pattern) > 0 {
		switch pattern[0] {
		default:
			if len(str) == 0 || str[0] != pattern[0] {
				return false
			}
		case '?':
			if len(str) == 0 && !simple {
				return false
			}
		case '*':
			return deepMatchRune(str, pattern[1:], simple) ||
				(len(str) > 0 && deepMatchRune(str[1:], pattern, simple))
		}
		str = str[1:]
		pattern = pattern[1:]
	}
	return len(str) == 0 && len(pattern) == 0
}
